<?php


namespace EchoPHP\Cache;


class RedisStore implements CacheContract {

    /**
     * redis实例
     * @var \Redis
     */
    protected $redis;

    /**
     * 缓存键名前缀
     * @var
     */
    protected $prefix;

    public function __construct($redis, $prefix = '') {
        $this->redis = $redis;
        $this->setPrefix($prefix);
    }

    /**
     * @inheritDoc
     */
    public function has($key) {
        if (!$this->redis) {
            return false;
        }

        return (bool)$this->redis->exists($this->getRealKey($key));
    }

    /**
     * @inheritDoc
     */
    public function get($key, $default = null) {
        if (!$this->redis) {
            return $default;
        }

        $value = $this->redis->get($this->getRealKey($key));
        if ($value === false) {
            return $default;
        }
        return $this->unserialize($value);
    }

    /**
     * @inheritDoc
     */
    public function pull($key, $default = null) {
        if (!$this->redis) {
            return $default;
        }

        $value = $this->get($key, $default);
        if (!is_null($value)) {
            $this->delete($key);
        }
        return $value;
    }

    /**
     * @inheritDoc
     */
    public function set($key, $value, $seconds) {
        if (!$this->redis) {
            return false;
        }

        if (intval($seconds) == 0) {
            return (bool)$this->redis->set(
                $this->getRealKey($key), $this->serialize($value)
            );
        }
        return (bool)$this->redis->setex(
            $this->getRealKey($key), (int)max(1, $seconds), $this->serialize($value)
        );
    }

    /**
     * @inheritDoc
     */
    public function add($key, $value, $seconds) {
        if (!$this->redis) {
            return false;
        }
        if ($this->has($key)) {
            return false;
        }
        return $this->set($key, $value, $seconds);
    }

    /**
     * @inheritDoc
     */
    public function increment($key, $step = 1) {
        if (!$this->redis) {
            return false;
        }

        return $this->redis->incrBy($this->getRealKey($key), $step);
    }

    /**
     * @inheritDoc
     */
    public function decrement($key, $step = 1) {
        if (!$this->redis) {
            return false;
        }
        if (!$this->redis) {
            return false;
        }

        return $this->redis->decrBy($this->getRealKey($key), $step);
    }

    /**
     * @inheritDoc
     */
    public function delete($key) {
        return (bool)$this->redis->delete($this->getRealKey($key));
    }

    /**
     * @inheritDoc
     */
    public function flush() {
        return $this->redis->flushDB();
    }

    /**
     * 设置前缀
     * @param $prefix
     */
    protected function setPrefix($prefix) {
        $this->prefix = empty($prefix) ? '' : ($prefix . ':');
    }

    /**
     * 获取存储键名
     * @param $key
     * @return string
     */
    protected function getRealKey($key) {
        return $this->prefix . $key;
    }

    /**
     * 序列化数据
     * @param $value
     * @return int|string
     */
    protected function serialize($value) {
        return is_numeric($value) ? $value : serialize($value);
    }

    /**
     * 反序列化数据
     * @param $value
     * @return int|mixed|string
     */
    protected function unserialize($value) {
        return is_numeric($value) ? $value : unserialize($value);
    }
}